Módulo 4 · Guia Interativo · 2026

Transformers — A Revolução

O paper "Attention is All You Need" (2017) e a arquitetura que mudou tudo. Self-attention, multi-head attention, BERT, GPT — a base dos LLMs modernos.

⚡ Self-Attention 👁️ Multi-Head 📍 Positional 🏗️ Encoder/Decoder 🚀 BERT/GPT

1 O que é um Transformer?

A arquitetura que mudou tudo em 2017 — e por que ela substituiu RNNs.

💡 Analogia
👥Um Transformer é como uma sala de reunião onde todos podem falar com todos ao mesmo tempo. Não precisa esperar a vez — cada pessoa (token) olha diretamente para todas as outras e decide o que é relevante.
Diferente das RNNs que processam tokens sequencialmente (um por vez), Transformers processam todos os tokens em paralelo. Cada token "olha" para todos os outros através de self-attention, capturando relações de qualquer distância instantaneamente.

O paper que mudou tudo

Em junho de 2017, pesquisadores do Google publicaram "Attention is All You Need". A ideia central: abandonar completamente RNNs e CNNs para processamento de linguagem, usando apenas mechanisms de atenção.

❌ RNN/LSTM (antes)

Processamento: sequencial (token por token)

Dependências longas: difíceis de capturar

Paralelização: impossível

Lento e limitado para sequências longas.

✅ Transformer (depois)

Processamento: paralelo (todos os tokens)

Dependências longas: capturadas diretamente

Paralelização: total (usa GPUs eficientemente)

Rápido, escalável, captura contexto de longo alcance.

Por que Transformers dominaram?

Paralelização total

Todos os tokens processados simultaneamente. Treinamento 10x mais rápido que RNNs.

🎯

Self-attention

Cada token conecta-se diretamente a qualquer outro, independente da distância.

📏

Escalabilidade

Pode ser empilhado em centenas de camadas (GPT-3 tem 96).

🌐

Versatilidade

Funciona para texto, imagem, áudio, vídeo — qualquer sequência.

💡 Impacto: em 5 anos (2017-2022), Transformers substituíram RNNs em praticamente todas as tarefas de NLP. BERT (2018), GPT-2 (2019), GPT-3 (2020), ChatGPT (2022) — todos são Transformers.

2 Self-Attention — o coração do Transformer

Como cada token "olha" para todos os outros e decide o que é relevante.

💡 Analogia
🔍Self-attention é como ler uma frase e, para cada palavra, perguntar: "quais outras palavras são importantes para entender esta?". A palavra "ele" olha para "João" e descobre que se refere a ele.
Para cada token, o modelo calcula scores de atenção com todos os outros tokens. Esses scores determinam quanto cada token "contribui" para a representação do token atual. É como uma rede de conexões dinâmicas que se adapta ao contexto.

A fórmula da atenção

# Self-attention (simplificado)
Attention(Q, K, V) = softmax(Q * K^T / √d_k) * V

# Onde:
# Q (Query) = "o que estou procurando?"
# K (Key) = "o que eu tenho?"
# V (Value) = "qual meu conteúdo?"
# d_k = dimensão dos vetores (normalização)

# Para cada token:
# 1. Calcula Q, K, V (projeções lineares do token)
# 2. Q * K^T = scores de atenção (similaridade com todos)
# 3. softmax = normaliza para probabilidades (soma = 1)
# 4. Multiplica por V = combinação ponderada dos valores

🎮 Simulador: Matriz de Atenção

Cada célula mostra quanto a palavra da linha "olha" para a palavra da coluna. Valores mais claros = mais atenção. Clique em uma célula para ver detalhes.

Frase: "O contrato que assinamos em janeiro venceu"

Selecionado: clique em uma célula

Interpretação: note como "venceu" olha fortemente para "contrato" (sujeito), e "que" olha para "contrato" (pronome relativo).

Exemplo prático: resolvendo ambiguidade

# Frase ambígua
"O banco que fica na esquina faliu."

# Self-attention descobre:
# - "banco" olha para "faliu" → contexto financeiro
# - "banco" NÃO olha fortemente para "esquina"
# - Conclusão: "banco" = instituição financeira, não assento

# Comparação com RNN:
# - RNN processa sequencialmente
# - Quando chega em "faliu", já processou "banco" há 5 tokens
# - Informação pode ter se perdido
# - Transformer: "faliu" olha diretamente para "banco"
💡 No RAG: quando um chunk é processado por um modelo de embedding (baseado em Transformer), o self-attention captura relações entre todas as palavras do chunk. É por isso que embeddings capturam significado contextual!

3 Multi-Head Attention — múltiplas perspectivas

Em vez de uma única atenção, várias "cabeças" capturando diferentes tipos de relações.

💡 Analogia
👥Multi-head attention é como ter vários especialistas analisando a mesma frase. Um especialista foca em sintaxe, outro em semântica, outro em referências, outro em tempo verbal. No final, combinam suas opiniões.
Em vez de uma única função de atenção, Transformers usam múltiplas "cabeças" de atenção em paralelo. Cada cabeça aprende a focar em diferentes tipos de relações. Isso permite ao modelo capturar múltiplos aspectos da linguagem simultaneamente.

🎮 Simulador: diferentes cabeças, diferentes padrões

Clique nas abas para ver como cada "cabeça" do Transformer foca em padrões diferentes da mesma frase.

🔗 Cabeça 1: Referência
📍 Cabeça 2: Posição
🎯 Cabeça 3: Semântica
⏰ Cabeça 4: Sintaxe

O que cada cabeça aprende?

🔗

Cabeças de Referência

Pronomes ("ele", "ela") olhando para seus antecedentes. Resolve ambiguidade de coreferência.

📍

Cabeças de Posição

Tokens olhando para vizinhos próximos. Captura sintaxe local e padrões adjacentes.

🎯

Cabeças Semânticas

Palavras relacionadas por significado (sinônimos, tópicos). Captura relações de conteúdo.

Cabeças Sintáticas

Sujeito-verbo, modificadores distantes. Captura estrutura gramatical.

Código Python: Multi-Head Attention

import torch
import torch.nn as nn
import torch.nn.functional as F

class MultiHeadAttention(nn.Module):
    def __init__(self, d_model=512, num_heads=8):
        super().__init__()
        self.d_model = d_model
        self.num_heads = num_heads
        self.d_k = d_model // num_heads  # 64 por cabeça

        # Projeções lineares para Q, K, V
        self.W_q = nn.Linear(d_model, d_model)
        self.W_k = nn.Linear(d_model, d_model)
        self.W_v = nn.Linear(d_model, d_model)
        self.W_o = nn.Linear(d_model, d_model)

    def forward(self, x):
        batch_size = x.size(0)

        # 1. Projeções lineares
        Q = self.W_q(x)  # (batch, seq_len, d_model)
        K = self.W_k(x)
        V = self.W_v(x)

        # 2. Reshape para múltiplas cabeças
        Q = Q.view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2)
        K = K.view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2)
        V = V.view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2)

        # 3. Attention scores
        scores = torch.matmul(Q, K.transpose(-2, -1)) / (self.d_k ** 0.5)
        attn = F.softmax(scores, dim=-1)

        # 4. Aplica atenção aos valores
        out = torch.matmul(attn, V)

        # 5. Concatena cabeças e projeta
        out = out.transpose(1, 2).contiguous().view(batch_size, -1, self.d_model)
        return self.W_o(out)

# Uso
mha = MultiHeadAttention(d_model=512, num_heads=8)
x = torch.randn(1, 10, 512)  # 10 tokens, 512 dimensões
out = mha(x)
print(out.shape)  # torch.Size([1, 10, 512])
💡 Números típicos: BERT-base tem 12 cabeças, BERT-large tem 16. GPT-3 tem 96 cabeças (em algumas camadas). Mais cabeças = mais capacidade de capturar relações diversas, mas mais computação.

4 Positional Encoding — a ordem importa

Como Transformers sabem a ordem das palavras, já que processam tudo em paralelo.

💡 Analogia
🔢Positional encoding é como numerar as páginas de um livro. Sem números, você sabe o conteúdo, mas não a ordem. Transformers adicionam "números de página" aos tokens para preservar a sequência.
Como Transformers processam todos os tokens em paralelo (não sequencialmente como RNNs), eles perdem a informação de ordem. "João ama Maria" e "Maria ama João" teriam a mesma representação sem positional encoding. A solução: adicionar um vetor de posição a cada token.

A fórmula

# Positional Encoding (original do paper)
PE(pos, 2i) = sin(pos / 10000^(2i/d_model))
PE(pos, 2i+1) = cos(pos / 10000^(2i/d_model))

# Onde:
# pos = posição do token na sequência (0, 1, 2, ...)
# i = índice da dimensão (0, 1, 2, ..., d_model/2)
# d_model = dimensão do modelo (ex: 512, 768)

# Resultado: cada posição tem um vetor único
# Adiciona ao embedding do token:
token_with_pos = token_embedding + positional_encoding

Por que sin/cos?

🔄

Relativo

Permite ao modelo aprender a atender a posições relativas (ex: "2 tokens antes").

📏

Escalável

Funciona para sequências de qualquer comprimento (não precisa treinar para cada posição).

🎯

Único

Cada posição tem um vetor único, permitindo distinguir "João ama Maria" de "Maria ama João".

Exemplo prático

# Frase: "O gato dormiu"

# Sem positional encoding:
# - "O gato dormiu" e "dormiu gato O" → mesma representação
# - Modelo não sabe a ordem!

# Com positional encoding:
token_0 = embed("O") + PE(0)
token_1 = embed("gato") + PE(1)
token_2 = embed("dormiu") + PE(2)

# Agora "O gato dormiu" ≠ "dormiu gato O"
# Cada token sabe sua posição na sequência
⚠️ Evolução moderna: modelos recentes (LLaMA, GPT-NeoX) usam Rotary Positional Encoding (RoPE), que rotaciona os vetores em vez de somar. Mais eficiente e melhor para extrapolação (sequências mais longas que as do treino).

5 Arquitetura: Encoder vs Decoder

Duas variantes principais: BERT (encoder) e GPT (decoder) — e quando usar cada uma.

💡 Analogia
📖Encoder é como um leitor que lê o livro inteiro e faz um resumo (entende o contexto completo). Decoder é como um escritor que escreve palavra por palavra, olhando para o que já escreveu (gera texto sequencialmente).

🏗️ As duas arquiteturas

🔵 Encoder (BERT)

Input Embeddings + Positional
Tokens viram vetores + posição
Multi-Head Self-Attention
Cada token olha para TODOS os outros
Feed-Forward Network
Transforma representações
× N camadas (12 em BERT-base)
Empilhamento de blocos
Output: representações contextuais
Cada token tem um vetor rico em contexto

Uso: classificação, NER, embeddings, QA.

🟢 Decoder (GPT)

Input Embeddings + Positional
Tokens viram vetores + posição
Masked Self-Attention
Cada token olha só para os ANTERIORES
Feed-Forward Network
Transforma representações
× N camadas (96 em GPT-3)
Empilhamento de blocos
Output: próximo token
Prediz a próxima palavra

Uso: geração de texto, chatbots, LLMs.

A diferença crucial: masking

🔵 Encoder (BERT) — bidirecional

Cada token vê todos os outros (antes e depois).

Ex: "gato" em "O gato dormiu" vê "O" E "dormiu".

✅ Ótimo para entender contexto completo.

🟢 Decoder (GPT) — unidirecional

Cada token vê só os anteriores (máscara causal).

Ex: "dormiu" em "O gato dormiu" vê "O" e "gato", mas não o que vem depois.

✅ Essencial para geração (não trapacear olhando o futuro).

Modelos famosos e suas arquiteturas

Modelo Arquitetura Ano Uso principal
BERT 🔵 Encoder 2018 Classificação, NER, embeddings
RoBERTa 🔵 Encoder 2019 BERT melhorado
GPT-2 🟢 Decoder 2019 Geração de texto
T5 🔵+🟢 Encoder-Decoder 2019 Tradução, sumarização
GPT-3 🟢 Decoder 2020 LLM generativo
Claude 🟢 Decoder 2023 LLM assistente
Llama 3 🟢 Decoder 2024 LLM open-source
💡 Regra prática: se você quer entender texto (classificar, extrair info, embeddings) → use encoder (BERT). Se você quer gerar texto (chatbot, escrita) → use decoder (GPT).

6 Outras peças do quebra-cabeça

Feed-forward, LayerNorm, residual connections — o que mais compõe um Transformer.

Feed-Forward Network (FFN)

Após a atenção, cada token passa por uma rede neural simples (2 camadas lineares com ativação no meio). É onde o modelo "pensa" sobre a informação coletada pela atenção.

# Feed-Forward Network (posição por posição)
FFN(x) = ReLU(x * W1 + b1) * W2 + b2

# Tipicamente:
# - W1 expande: 512 → 2048 (4x)
# - ReLU ativa
# - W2 comprime: 2048 → 512

Layer Normalization

Normaliza os valores ao longo da dimensão das features. Estabiliza o treinamento e acelera convergência.

# LayerNorm (simplificado)
LayerNorm(x) = γ * (x - μ) / √(σ² + ε) + β

# Onde:
# μ = média dos valores do token
# σ² = variância
# γ, β = parâmetros aprendíveis
# ε = pequena constante para estabilidade

Residual Connections (Skip Connections)

💡 Analogia
🔁Residual connections são como atalhos em uma rodovia. Se o caminho principal (camada complexa) for ruim, o atalho garante que a informação original ainda chegue ao destino.
# Residual connection
output = x + SubLayer(x)

# Em vez de:
output = SubLayer(x)

# O "+ x" permite que o gradiente flua diretamente
# mesmo se SubLayer for problemático

O bloco completo do Transformer

# Um bloco do encoder (BERT)
x = x + MultiHeadAttention(LayerNorm(x))  # atenção + residual
x = x + FeedForward(LayerNorm(x))         # FFN + residual

# Um bloco do decoder (GPT)
x = x + MaskedMultiHeadAttention(LayerNorm(x))
x = x + FeedForward(LayerNorm(x))

# Empilha N desses blocos (12, 24, 96...)
💡 Por que funciona: residual connections + LayerNorm permitem treinar redes com centenas de camadas sem vanishing gradient. É o segredo por trás de GPT-3 (96 camadas) e modelos ainda maiores.

7 Conexão com RAG

Como tudo que você aprendeu aqui se aplica ao Módulo 7 (RAG).

💡 Conexão
🔗Os embeddings que usamos em RAG são gerados por modelos Transformer (como nomic-embed-text, baseado em BERT). Os LLMs que geram as respostas (GPT, Llama, Claude) também são Transformers. Entender essa arquitetura é essencial para entender RAG.

Conceitos que se conectam

Conceito de Transformers Aplicação em RAG
Self-Attention Permite que embeddings capturem contexto completo do chunk. "timeout" olha para "endpoint" e entende o significado.
Multi-Head Attention Diferentes cabeças capturam diferentes aspectos: sintaxe, semântica, referências. Embeddings ricos.
Encoder (BERT) Modelos de embedding (nomic-embed-text) são encoders. Geram vetores que representam chunks inteiros.
Decoder (GPT) LLMs que geram respostas (Llama, Claude) são decoders. Recebem contexto do RAG e geram texto.
Positional Encoding Preserva ordem das palavras nos chunks. Importante para chunks longos com dependências distantes.
Context Window Limite de tokens que o Transformer pode processar. Define tamanho máximo dos chunks em RAG.

O pipeline RAG com Transformers

# Pipeline completo usando Transformers

# 1. Indexação (usa ENCODER)
chunks = chunk_document(doc)
encoder = load_model("nomic-embed-text")  # baseado em BERT
for chunk in chunks:
    embedding = encoder(chunk)  # self-attention captura contexto
    vector_db.add(embedding, chunk)

# 2. Consulta (usa ENCODER + DECODER)
question = "Qual o timeout do endpoint /v2/sync?"
q_embedding = encoder(question)  # mesmo modelo de embedding
chunks = vector_db.search(q_embedding, top_k=5)

# 3. Geração (usa DECODER)
llm = load_model("llama3.1:8b")  # decoder Transformer
prompt = format_prompt(chunks, question)
answer = llm.generate(prompt)  # gera token por token

Por que o tamanho do contexto importa?

Transformers têm um limite de tokens que podem processar (context window):

Isso define o tamanho máximo dos chunks em RAG. Chunks muito grandes não cabem; chunks muito pequenos perdem contexto.

💡 No Módulo 7 (RAG): você vai usar modelos de embedding (encoders) para indexar chunks e LLMs (decoders) para gerar respostas. Tudo que aprendemos aqui é a base!

🎯 Quiz — teste seu conhecimento

Clique em uma alternativa para ver se acertou.

1. Qual a principal vantagem dos Transformers sobre RNNs?
São mais simples de implementar
Processam tokens em paralelo e capturam dependências de longo alcance via self-attention
Não precisam de dados de treinamento
2. O que é self-attention?
Um tipo de função de ativação
Uma técnica de regularização
Mecanismo onde cada token calcula scores de atenção com todos os outros tokens da sequência
3. O que representam Q, K e V na fórmula de atenção?
Query (o que procuro), Key (o que tenho), Value (meu conteúdo)
Quality, Knowledge, Vocabulary
Quick, Kernel, Vector
4. Por que usamos multi-head attention?
Para tornar o modelo mais lento
Para que diferentes cabeças capturem diferentes tipos de relações (sintaxe, semântica, referência)
Para reduzir o número de parâmetros
5. Qual o papel do positional encoding?
Acelerar o treinamento
Reduzir o tamanho do modelo
Preservar a ordem das palavras, já que o Transformer processa tudo em paralelo
6. Qual a diferença entre Encoder (BERT) e Decoder (GPT)?
Encoder vê todos os tokens (bidirecional); Decoder vê só os anteriores (unidirecional)
Encoder é mais rápido; Decoder é mais preciso
Encoder usa ReLU; Decoder usa Sigmoid
7. Para que serve residual connection?
Aumentar o número de parâmetros
Permitir treinar redes muito profundas sem vanishing gradient, criando atalhos para o gradiente
Reduzir o tempo de inferência
8. Qual modelo é baseado em Encoder?
GPT-3
Llama 3
BERT
9. Como Transformers se conectam com RAG?
Modelos de embedding (encoders) indexam chunks; LLMs (decoders) geram respostas
Transformers não são usados em RAG
Apenas LLMs são usados, embeddings são de outro tipo
10. O que é "masked self-attention" no decoder?
Atenção que ignora todas as palavras
Cada token só pode olhar para tokens anteriores (não vê o futuro)
Atenção que só funciona com palavras em maiúsculas

O que vem a seguir?

Agora que você entende Transformers, vamos mergulhar nos Grandes Modelos de Linguagem.

🚀
Próximo módulo
Módulo 5 · LLMs — Grandes Modelos de Linguagem
GPT, Claude, Llama — como funcionam os modelos que geram texto. Pré-treinamento, fine-tuning, RLHF, context window e como escolher o modelo certo.

Conceitos que vamos construir aqui

📚

Pré-treinamento

Next token prediction em trilhões de tokens.

🎯

Fine-tuning (SFT)

Ajuste supervisionado para tarefas específicas.

👥

RLHF

Alinhamento com preferências humanas.

🌡️

Temperature

Controlando criatividade vs determinismo.

💡 Conexão com RAG: o LLM é o motor de geração do RAG. Entender como ele funciona (temperature, context window, tokens) ajuda a escrever prompts melhores e escolher o modelo certo para seu caso de uso.